﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.NewsLetters.Services
{
	public abstract class UserRecipientSourceProviderBase : IEmailListSourceProvider
	{
		protected ERPStore.Models.UserListFilter m_Filter;

		public UserRecipientSourceProviderBase(
			ERPStore.Services.IValidatorService validator
			, NewsLettersService newsLetterService
			, ERPStore.Logging.ILogger logger)
		{
			this.ValidatorService = validator;
			this.NewsLetterService = newsLetterService;
			this.Logger = logger;
		}

		protected ERPStore.Services.IValidatorService ValidatorService { get; private set; }
		protected NewsLettersService NewsLetterService { get; private set; }
		protected ERPStore.Logging.ILogger Logger { get; private set; }

		public abstract void Initialize(Models.EmailListSource source);
		public abstract string SourceTypeId { get; }
		public abstract string DisplayName { get; }
		public virtual IList<ERPStore.Models.BrokenRule> Validate()
		{
			return new List<ERPStore.Models.BrokenRule>();
		}
		public virtual string GetSerializedSettings()
		{
			return m_Filter.SerializeToXml();
		}

		public virtual IEnumerable<Models.EmailRecipient> GetList(int pageIndex, int pageSize, out int count)
		{
			count = 0;
			if (m_Filter == null)
			{
				return null;
			}
			var result = new List<Models.EmailRecipient>();
			var list = NewsLetterService.GetUserListByFilter(m_Filter, pageIndex, pageSize, out count);
			list.RemoveAll(i => i.Email.IsNullOrTrimmedEmpty());

			Logger.Info("Loading user list {0} / {1}", (pageIndex + 1) * pageSize, count);
			var emailList = list.Select(i => i.Email.Trim()).Distinct();
			var recipientList = NewsLetterService.GetEmailRecipientByEmailList(emailList);
			foreach (var item in list)
			{
				if (item.Email.IsNullOrTrimmedEmpty())
				{
					continue;
				}
				bool saveRequested = false;
				var rcp = recipientList.FirstOrDefault(i => i.Email.Equals(item.Email.Trim(), StringComparison.InvariantCultureIgnoreCase));
				if (rcp == null)
				{
					rcp = AutoMapper.Mapper.Map<Models.EmailRecipient>(item);
					saveRequested = true;
				}
				else
				{
					bool bl = rcp.IsBlackListed;
					var copy = AutoMapper.Mapper.Map<ERPStore.Models.User, Models.EmailRecipient>(item, rcp);
					if (copy.City != rcp.City
						|| copy.CorporateName != rcp.CorporateName
						|| copy.CountryCode != rcp.CountryCode
						|| copy.Email != rcp.Email
						|| copy.EmailVerificationStatus != rcp.EmailVerificationStatus
						|| copy.FirstName != rcp.FirstName
						|| copy.LastName != rcp.LastName
						|| copy.Presentation != rcp.Presentation
						|| copy.ZipCode != rcp.ZipCode)
					{
						copy.IsBlackListed = bl;
						rcp = copy;
						saveRequested = true;
					}
				}
				if (saveRequested)
				{
					try
					{
						NewsLetterService.SaveEmailRecipient(rcp);
					}
					catch (Exception ex)
					{
						Logger.Error(ex);
						continue;
					}
				}
				if (!rcp.IsBlackListed)
				{
					result.Add(rcp);
				}
			}

			return result;
		}

	}
}
